package org.lsp.opencvauto.weixin;

import org.lsp.opencvauto.doman.MessageCoordinatesAndContent;
import org.lsp.opencvauto.image.ImageDispose;
import org.lsp.opencvauto.ocr.OCRInstanst;
import org.opencv.core.*;
import org.opencv.core.Point;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;


import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.opencv.imgcodecs.Imgcodecs.imwrite;

/**
 * 微信
 * */
@Component
public class WeiXin {


    private static final Logger log = LoggerFactory.getLogger(WeiXin.class);

    /*
    * 识别微信最左边的消息通知
    * */
    public String identifyMessages(String imagePath){
        // 1. 读取图像
        Mat src = Imgcodecs.imread(imagePath);

        // 2. 转换为HSV颜色空间（便于颜色分割）
        Mat hsv = new Mat();
        Imgproc.cvtColor(src, hsv, Imgproc.COLOR_BGR2HSV);
//        Imgcodecs.imwrite("1.jpg", hsv);
        Mat gray = new Mat();
        Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);
//        imwrite("3.jpg", gray);
        Mat binary = new Mat();
        Imgproc.threshold(gray, binary, 190, 255, Imgproc.THRESH_BINARY); // 阈值可调整 200
        imwrite("4.jpg", binary);
        log.info("图片吃寸：{}X{}",binary.cols(),binary.rows());
        String result = OCRInstanst.doNumericOCR("./4.jpg","number");
        log.info("图片识别结果{}",result);
        return result;
    }

    /**
     * 识别微信左侧消息聊天栏中那个消息栏通知。
     * 捕获这个消息圆点的坐标和圆点的消息内容
     * */
    public List<MessageCoordinatesAndContent> messageBarNotifications() {
        // 图像预处理
        Mat src = preprocessImage();
        //  检测红色未读标识
       return detectRedIcons(src);
    }

    /**
     * 图像预处理：读取图像并转换到HSV颜色空间
     */
    private Mat preprocessImage() {
        Mat src = Imgcodecs.imread("./messageqvyv.png");
        if (src.empty()) {
            throw new RuntimeException("无法读取源图像");
        }
        return src;
    }

    /**
     * 检测红色未读标识并保存裁剪区域
     *  返回消息圆点坐标（x，y）和宽高
     */
    private List<MessageCoordinatesAndContent> detectRedIcons(Mat src) {
        List<MessageCoordinatesAndContent> rects = new ArrayList<>();
        // 转换到HSV颜色空间
        Mat hsv = new Mat();
        Imgproc.cvtColor(src, hsv, Imgproc.COLOR_BGR2HSV);

        // 定义红色范围
        Scalar lowerRed = new Scalar(0, 100, 100);
        Scalar upperRed = new Scalar(10, 255, 255);

        // 创建红色掩膜
        Mat mask = new Mat();
        Core.inRange(hsv, lowerRed, upperRed, mask);

        // 查找轮廓并过滤有效区域
        List<MatOfPoint> contours = new ArrayList<>();
        Imgproc.findContours(mask, contours, new Mat(),
                Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

        for (MatOfPoint contour : contours) {
            double area = Imgproc.contourArea(contour);
            if (area > 100) {  // 面积阈值过滤
                MessageCoordinatesAndContent messageCoordinatesAndContent = new MessageCoordinatesAndContent();
                Rect boundingBox = Imgproc.boundingRect(contour);
                messageCoordinatesAndContent.setRect(boundingBox);
                rects.add(messageCoordinatesAndContent);
                // 输出检测信息
                log.info("检测到红色未读标识");
                log.info("消息区域面积：{}", area);
                log.info("图片中的位置x,y: {},{} , 图片宽-高: {} - {}", boundingBox.x, boundingBox.y, boundingBox.width,boundingBox.height);
                // 裁剪并保存红色图标
                Mat redIcon = new Mat(src, boundingBox);
                Imgcodecs.imwrite("red_icon.png", redIcon);
                //执行OCR识别
                String message = performOCR();
                messageCoordinatesAndContent.setMessage(message);
                break;
            }
        }
        return rects;
    }

    /**
     * 执行OCR识别前的图像处理流程
     * 返回图片识别结果
     */
    private String performOCR() {
        // 读取并预处理OCR图像
        Mat ocrImage = Imgcodecs.imread("red_icon.png");
        if (ocrImage.empty()) {
            throw new RuntimeException("无法读取OCR目标图像");
        }

        // 图像处理流程
        Imgproc.cvtColor(ocrImage, ocrImage, Imgproc.COLOR_BGR2HSV);
        Imgproc.cvtColor(ocrImage, ocrImage, Imgproc.COLOR_BGR2GRAY);
        Imgproc.threshold(ocrImage, ocrImage, 150, 255, Imgproc.THRESH_BINARY);
        Imgcodecs.imwrite("red_icon1.png", ocrImage);

        // 进一步二值化处理
        Mat src1 = Imgcodecs.imread("red_icon1.png");
        if (src1.empty()) {
            throw new RuntimeException("无法读取OCR处理后图像");
        }

        Mat gray = new Mat();
        Imgproc.cvtColor(src1, gray, Imgproc.COLOR_BGR2GRAY);
        Mat binary = new Mat();
        Imgproc.threshold(gray, binary, 200, 255, Imgproc.THRESH_BINARY);

        // 轮廓检测与掩膜处理
        List<MatOfPoint> contours1 = new ArrayList<>();
        Mat hierarchy = new Mat();
        Imgproc.findContours(binary, contours1, hierarchy,
                Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

        Mat mask1 = Mat.zeros(binary.size(), binary.type());

        // 绘制轮廓
        for (int i = 0; i < contours1.size(); i++) {
            Imgproc.drawContours(mask1, contours1, i, new Scalar(255), -1);
        }
        // 位运算提取结果
        Mat result = new Mat();
        Core.bitwise_xor(binary, mask1, result);
        Imgproc.resize(result, result, new Size(46,46), 0,0,Imgproc.INTER_CUBIC);
        log.info("图片的大小是：{}x{}", result.cols(), result.rows());
        Imgcodecs.imwrite("masked_result.jpg", result);
        // 执行OCR识别
        String ocrResult = OCRInstanst.doNumericOCR("./masked_result.jpg", "number1");
        log.info("图片识别结果是：{}", ocrResult);
        return ocrResult;
    }

    /**
     * 发送聊天窗口发送消息
     * */
    public void sendMessage(String message) {
        //获取图片中的聊天窗口的输入框坐标以及信息
        Map<String, Object> inputMap = ImageDispose.matchTemplate("matchTemplate/messagerecognition/Input_massages.png", "./weixin.png");
        Mat inputMat= (Mat) inputMap.get("result");
        Mat templateGray =(Mat) inputMap.get("templateGray");
        Core.MinMaxLocResult minMaxLocResult = Core.minMaxLoc(inputMat);
        Point maxLoc = minMaxLocResult.maxLoc;
        int inputx = (int) maxLoc.x;
        int inputy =  (int)maxLoc.y;
        log.info("输入框的坐标是 x:{} y:{}  长 ：{} 宽：{} ",inputx,inputy,templateGray.cols(),templateGray.rows());
        Rect rect2=new Rect(inputx,inputy,templateGray.cols(),templateGray.rows());
        Mat imread = Imgcodecs.imread("./weixin.png");
        //输入框坐标信息
        Mat inputMassageMat = new Mat(imread, rect2);
        //读取发送的消息
        try {
            Robot robot=new Robot();
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            clipboard.setContents(new StringSelection(message), null);
            simulatePaste(robot);
            //回车发送消息
            robot.keyPress(KeyEvent.VK_ENTER);
            robot.keyRelease(KeyEvent.VK_ENTER);
        } catch (AWTException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 模拟粘贴操作（Ctrl + V 或 Command + V，根据操作系统自动适配）
     */
    private static void simulatePaste(Robot robot) {
        if (isMac()) {
            // Mac 系统：Command + V
            robot.keyPress(KeyEvent.VK_META); // Command 键
            robot.keyPress(KeyEvent.VK_V);
            robot.keyRelease(KeyEvent.VK_V);
            robot.keyRelease(KeyEvent.VK_META);
        } else {
            // Windows 系统：Ctrl + V
            robot.keyPress(KeyEvent.VK_CONTROL);
            robot.keyPress(KeyEvent.VK_V);
            robot.keyRelease(KeyEvent.VK_V);
            robot.keyRelease(KeyEvent.VK_CONTROL);
        }
        log.info("已模拟粘贴操作");
    }

    /**
     * 判断当前操作系统是否为 Mac
     */
    private static boolean isMac() {
        return System.getProperty("os.name").toLowerCase().contains("mac");
    }

}
